Saltar al contenido principal

Deploy de cloud functions

En esta sección vamos a deployar en GCP, la cloud function desarrollada en la sección anterior
mediante gitlab-ci.

Gitlab CI

Buildear función en local.

npm run build

Esto genera una carpeta dist la cual contiene el artifact utilizado para deployar la función.

Nota: En el hipotetico caso que aparezca el siguiente error al buildear.

This file is being treated as an ES module because it has a '.js' file extension and '/home/julian/sils/keeper/cf/delete-infractions/package.json' contains "type": "module". To treat it as a CommonJS script, rename it to use the '.cjs' file extension.

Debem quitar la propiedad type: "module" de package.json.

Crear yml de gitlab CI

touch .gitlab-ci.yml

En el archivo creado copiar y pegar el siguiente contenido:

image: node:20

stages:
- build

build:
stage: build
script:
- npm ci
- npm run build
- ls -la
artifacts:
paths:
- dist
expire_in: 30 mins
cache:
key: ${CI_COMMIT_REF_SLUG}
paths:
- node_modules/
- .npm/
rules:
- if: ($CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "master" || $CI_COMMIT_BRANCH == "master")

Crear runner de gitlab.

Para que se ejecute el pipeline en gitlab es necesario registrar un runner en la instancia.

Conectarse por ssh a gitlab

gcloud compute ssh --zone "us-central1-a" "gitlab" --project "sils-keeper-infra"

Una vez conectado necesitamos un token generado en el proyecto de gitlab, para esto necesitamos tener
el código subido a un repositorio en gitlab.sils.tech.

En la pagina principal del repositorio ingresar a Settings --> CI/CD --> Runners y buscar el panel
donde figura el registration token.

Registration token

Registrar el runner

Ahora en la instancia de gitlab que nos conectamos anteriormente por ssh ingresamos el siguiente comando:

sudo gitlab-runner register

A continuación nos pide una serie de datos:

  • URL: https://gitlab.sils.tech/
  • El registration token que figura en el repo.
  • Una descripción del runner (puede dejarse vacio)
  • Una descripción del runner (puede dejarse vacio)
  • Tags que identifiquen al runner
  • Notas de mantenimiento
  • Executor: Elegir docker
  • Imagen de docker: ruby:2.7

Verificar los runners

sudo gitlab-runner verifiy

Despues de ejecutar ese comando volvemos a la pantalla de Settings de gitlab y en runners deberiamos
ver el runner recien creado.

alt text

Le damos en edit y deberiamos tenerlo configurado de la siguiente manera:

alt text

Ejecutar pipeline

A continuación ejecutamos el pipeline configurado en el yaml que subimos previamente, esto lo podemos
hacer pusheando cambios a master(o al branch origen donde esten trabajando) o directamente acceder a la
sección CI/CD --> Pipelines --> Run Pipeline.
La primera vez que se ejecuta un pipeline con un runner nuevo suele llevar un tiempo para ejecutarse, paciencia...

Al terminar el pipeline deberian tener una salida similar a esta.

$ ls -la
total 572
drwxrwxrwx 7 root root 4096 Mar 28 14:22 .
drwxrwxrwx 4 root root 4096 Mar 27 19:18 ..
-rw-rw-rw- 1 root root 14 Mar 27 19:18 .dockerignore
-rw-rw-rw- 1 root root 59 Mar 27 19:18 .eslintignore
-rw-rw-rw- 1 root root 338 Mar 27 19:18 .eslintrc
-rw-rw-rw- 1 root root 551 Mar 27 19:18 .gcloudignore
drwxrwxrwx 6 root root 4096 Mar 28 14:21 .git
-rw-rw-rw- 1 root root 214 Mar 28 14:21 .gitignore
-rw-rw-rw- 1 root root 276 Mar 27 19:18 .gitlab-ci.yml
-rw-rw-rw- 1 root root 4443 Mar 27 19:18 Jenkinsfile
-rw-rw-rw- 1 root root 172 Mar 27 19:18 babel.config.js
drwxr-xr-x 3 root root 4096 Mar 28 14:22 dist
-rw-rw-rw- 1 root root 761 Mar 27 19:18 index.js
-rw-rw-rw- 1 root root 740 Mar 27 19:18 jest.config.js
drwxr-xr-x 699 root root 20480 Mar 28 14:22 node_modules
-rw-rw-rw- 1 root root 483471 Mar 28 14:21 package-lock.json
-rw-rw-rw- 1 root root 1482 Mar 27 19:18 package.json
-rw-rw-rw- 1 root root 333 Mar 27 19:18 sonar-project.properties
drwxrwxrwx 2 root root 4096 Mar 27 19:18 src
drwxrwxrwx 2 root root 4096 Mar 27 19:18 test
Uploading artifacts for successful job
00:02
Uploading artifacts...
dist: found 9 matching artifact files and directories
Uploading artifacts as "archive" to coordinator... 201 Created id=16826 responseStatus=201 Created token=64_K5FbL
Cleaning up project directory and file based variables
00:00
Job succeeded

Crear step de deploy y environment dev

Ahora el siguiente paso ya es crear el ambiente dev de la función y a su vez el job de
deploy de la misma.

Crear nueva rama dev

Desde la rama master ejecutar:

git checkout -b dev
git push origin dev

Una vez pusheada la rama dev al repositorio remoto, entrar a Settings --> Repository --> Branch defaults
y en esa sección definir a la rama dev como la por defecto (No olviden guardar los cambios).
Ahora en la misma sección ir a Protected Branches y crear una regla Protected para la rama dev
en la que solo Maintainers puedan pushear a la branch y Maintainers + Developers puedan mergear.

Setear variables de entorno.

Vamos a comenzar a generar los archivos de variables de entorno, entrar a Settings --> CI/CD --> Variables.
Presionar el boton Add variable y se abrira un modal como el siguiente.

alt text

En value copiar el service account de GCP del proyecto sils-des (Pediselos a estos).

Para la variable PROJECT_ID ingresar el proyecto de GCP correspondiente, en este caso seria sils-des.

Agregar step deploy:dev

En el archivo .gitlab-ci.yml pegar el siguiente contenido:

image: node:20-alpine

stages:
- build
- deploy

build:dev:
stage: build
script:
- npm ci
- npm run build
artifacts:
paths:
- dist
expire_in: 30 mins
cache:
key: ${CI_COMMIT_REF_SLUG}
paths:
- node_modules/
- .npm/
rules:
- if: ($CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "dev" || $CI_COMMIT_BRANCH == "dev")

deploy:dev:
stage: deploy
image: google/cloud-sdk:482.0.0-alpine
only:
- dev
dependencies:
- build:dev
script:
- gcloud auth activate-service-account --key-file=$SERVICE_ACCOUNT_DEV
- gcloud config set project $PROJECT_ID
environment: dev

Agregar comando de gcp para deployar la cf.

Si los jobs que subimos anteriormente pasaron ok, ahora debemos agregar el ultimo comando del job que es el deploy de la función en Google Cloud.

gcloud functions deploy myFunction --timeout 10s --memory 128MB --runtime nodejs18 --trigger-http --project ${GCP_PROJECT} --vpc-connector projects/${GCP_PROJECT}/locations/${GCP_ZONE}/connectors/${VPC_CONNECTOR} --env-vars-file ${ENV_FILE} --source=dist/

Necesitamos agregar las siguientes variables en el repo de gitlab(dejamos las de sils-des como ejemplo):

  • GCP_PROJECT=sils-des
  • GCP_ZONE=us-central1
  • VPC_CONNECTOR=sils-des-connector
  • ENV_FILE ---> Archivo .env necesario para el funcionamiento de la cf.

Si el deploy en gitlab pasa con exito deberian ver la función en estado activo en la consola de GCP

Troubleshooting

The npm ci command can only install with an existing package-lock.json

En el caso de tener un error referido a que falta el package-lock.json, el problema está
en que el package-lock.json está siendo ignorado por el .gitignore.